package hos.okhttp.http;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import hos.http.HttpBaseRequest;
import hos.http.HttpCall;
import hos.http.HttpCallback;
import hos.http.HttpRequest;
import hos.okhttp.utils.OkHttpUtils;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * <p>Title: OkHttpFactory </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2023-02-24 20:52
 */
public class OkHttpFactory implements HttpCall.Factory {

    private final OkHttpClient okHttpClient;

    public OkHttpFactory() {
        okHttpClient = initOkHttp(new OkHttpClient.Builder())
                .connectTimeout(120, TimeUnit.SECONDS)
                .readTimeout(120, TimeUnit.SECONDS)
                .writeTimeout(120, TimeUnit.SECONDS)
                .retryOnConnectionFailure(false)
                .build();
    }

    public OkHttpFactory(OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }

    protected OkHttpClient.Builder initOkHttp(OkHttpClient.Builder builder) {
        return builder;
    }

    @Override
    public <T> HttpCall<T> newCall(HttpRequest<?> request) {
        String url = request.getQueryUrl();
        // 获取请求 OkHttpClient
        OkHttpClient client = buildOkhttp(request);
        // 请求头部处理
        Headers.Builder headers = buildRequestHeader(request);
        // 处理请求体
        RequestBody requestBody = buildRequestBody(request);
        // 创建请求
        Request.Builder requestReal = buildRequest(request, url, headers.build(), requestBody);
        Call call = client.newCall(requestReal.build());
        return buildHttpCall(request, call);
    }

    /**
     * 创建请求
     */
    protected <T> HttpCall<T> buildHttpCall(HttpRequest<?> request, Call call) {
        return new HttpCall<T>() {
            /** @noinspection unchecked*/
            @Override
            public T execute() throws IOException {
                return (T) call.execute();
            }

            @Override
            public void enqueue(HttpCallback<T> callback) {
                OkHttpFactory.this.<T>enqueue(request, call, callback);
            }
        };
    }


    /**
     * 异步请求
     */
    protected <T> void enqueue(HttpRequest<?> request, Call call, HttpCallback<T> callback) {
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                if (callback != null) {
                    callback.onFailed(e);
                }
            }

            @SuppressWarnings("unchecked")
            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (callback != null) {
                    callback.onSuccess(request, (T) response);
                }
            }
        });
    }

    protected Request.Builder buildRequest(HttpBaseRequest<?> request, String url, Headers headers, RequestBody requestBody) {
        return OkHttpUtils.buildRequest(request, url, headers, requestBody);
    }

    /**
     * 处理请求体
     *
     * @param request 请求
     */
    protected RequestBody buildRequestBody(HttpBaseRequest<?> request) {
        return OkHttpUtils.buildRequestBody(request);
    }

    /**
     * 处理请求头
     *
     * @param request 请求
     */
    protected Headers.Builder buildRequestHeader(HttpBaseRequest<?> request) {
        return OkHttpUtils.buildRequestHeader(request);
    }

    protected OkHttpClient buildOkhttp(HttpBaseRequest<?> request) {
        return OkHttpUtils.buildOkhttp(okHttpClient, request);
    }

}
